package cn.tedu.luban.worker.webapi.service.impl;

import cn.tedu.luban.account.service.IAccountService;
import cn.tedu.luban.attach.service.IAttachService;
import cn.tedu.luban.commons.enums.worker.AuditStatusEnum;
import cn.tedu.luban.commons.exception.LubanServiceException;
import cn.tedu.luban.commons.pojo.account.model.Account;
import cn.tedu.luban.commons.pojo.area.dto.WorkerAreaDTO;
import cn.tedu.luban.commons.pojo.attach.dto.AttachDTO;
import cn.tedu.luban.commons.pojo.attach.dto.AttachUpdateDTO;
import cn.tedu.luban.commons.pojo.attach.model.Attach;
import cn.tedu.luban.commons.pojo.category.dto.WorkerCategoryDTO;
import cn.tedu.luban.commons.pojo.worker.dto.IdCardDTO;
import cn.tedu.luban.commons.pojo.worker.dto.WorkerCreateDTO;
import cn.tedu.luban.commons.pojo.worker.model.Worker;
import cn.tedu.luban.commons.pojo.worker.model.WorkerArea;
import cn.tedu.luban.commons.pojo.worker.model.WorkerCategory;
import cn.tedu.luban.commons.pojo.worker.vo.*;
import cn.tedu.luban.commons.restful.ResponseCode;
import cn.tedu.luban.commons.utils.PropertiesUtils;
import cn.tedu.luban.worker.service.IWorkerService;
import cn.tedu.luban.worker.webapi.mapper.AuditMapper;
import cn.tedu.luban.worker.webapi.mapper.WorkerAreaMapper;
import cn.tedu.luban.worker.webapi.mapper.WorkerCategoryMapper;
import cn.tedu.luban.worker.webapi.mapper.WorkerMapper;
import cn.tedu.luban.worker.webapi.utils.SecurityContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class WorkerServiceImpl implements IWorkerService {
    @Autowired
    private WorkerMapper workerMapper;

    @Autowired
    private WorkerAreaMapper workerAreaMapper;

    @Autowired
    private WorkerCategoryMapper workerCategoryMapper;

    @Autowired
    private AuditMapper auditMapper;

    @DubboReference
    private IAttachService dubboAttachService;

    @DubboReference
    private IAccountService dubboAccountService;

    @Value("${app.business.type}")
    private Integer businessType;

    @Value("${url}")
    private String url;

    //师傅入驻
    @Override
    @Transactional
    public Long createWorker(WorkerCreateDTO workerCreateDTO) {
        //获取当前登录用户id
        Long userId = SecurityContext.getUserId();
        //赋值userId
        workerCreateDTO.setUserId(userId);
        //师傅的详细身份信息，应该是使用用户上传的身份证图片，经过百度身份证验证接口，解析获得的
        IdCardVO idCardVO = new IdCardVO();
        idCardVO.setValid(true);
        idCardVO.setRealName("张无忌");
        idCardVO.setCardNo("123110199210101591");
        //判断验证结果
        if (idCardVO == null || !idCardVO.isValid()) {
            throw new LubanServiceException(ResponseCode.FORBIDDEN, "身份验证失败");
        }
        //调用新增工人师傅的方法
        Long id = saveWorker(userId, workerCreateDTO);
        //保存师傅和区域的关系
        saveArea(userId, workerCreateDTO.getWorkerAreaList());
        //保存师傅和施工品类的关系
        saveCategory(userId, workerCreateDTO.getWorkerCategoryList());
        //当前方法是标记有事务的,上面的数据库操作,要么都成功要么都失败
        //返回值是成功创建的工人师傅的id
        return id;
    }

    private void saveCategory(Long userId, List<WorkerCategoryDTO> workerCategoryList) {
        workerCategoryMapper.delete(userId);
        if (!CollectionUtils.isEmpty(workerCategoryList)) {
            workerCategoryList.forEach(workerCategoryDTO -> {
                workerCategoryDTO.setUserId(userId);
                WorkerCategory workerCategory = new WorkerCategory();
                BeanUtils.copyProperties(workerCategoryDTO, workerCategory);
                workerCategory.setGmtCreate(System.currentTimeMillis());
                workerCategory.setGmtModified(System.currentTimeMillis());
                workerCategory.setCreateUserId(userId);
                workerCategory.setModifiedUserId(userId);
                workerCategory.setCreateUserName("mock1");
                workerCategory.setModifiedUserName("mock1");
                workerCategory.setStatus(1);
                workerCategoryMapper.insert(workerCategory);
            });
        }
    }

    private void saveArea(Long userId, List<WorkerAreaDTO> workerAreaList) {
        //如果这个用户已经有区域信息,先删除
        workerAreaMapper.delete(userId);
        //判断用户选中的区域是否为空
        if (!CollectionUtils.isEmpty(workerAreaList)) {
            //遍历用户选中的所有区域集合
            workerAreaList.forEach(workerAreaDTO -> {
                workerAreaDTO.setUserId(userId);
                WorkerArea workerArea = new WorkerArea();
                BeanUtils.copyProperties(workerAreaDTO, workerArea);
                workerArea.setGmtCreate(System.currentTimeMillis());
                workerArea.setGmtModified(System.currentTimeMillis());
                workerArea.setCreateUserId(userId);
                workerArea.setModifiedUserId(userId);
                workerArea.setCreateUserName("mock1");
                workerArea.setModifiedUserName("mock1");
                workerArea.setStatus(1);
                workerAreaMapper.insert(workerArea);
            });
        }
    }

    private Long saveWorker(Long userId, WorkerCreateDTO workerCreateDTO) {
        //如果当前用户已经存在了删除掉
        workerMapper.delete(userId);
        //创建师傅对象，为所有属性赋值
        Worker worker = new Worker();
        BeanUtils.copyProperties(workerCreateDTO, worker);
        worker.setGmtCreate(System.currentTimeMillis());
        worker.setGmtModified(System.currentTimeMillis());
        worker.setCreateUserId(userId);
        worker.setModifiedUserId(userId);
        worker.setCreateUserName("mock1");
        worker.setModifiedUserName("mock1");
        worker.setStatus(1);
        worker.setAuditStatus(2);
        worker.setCertStatus(1);
        //将工人师傅新增到数据库
        workerMapper.insert(worker);
        //list中，保存的是当前注册师傅用户的身份证正反面图片信息
        List<AttachUpdateDTO> attachUpdateDTOList = new ArrayList<>();
        //遍历身份证信息
        for (IdCardDTO idCardDTO : workerCreateDTO.getAttachList()) {
            //将身份证正反面信息都获取，然后保存在attachUpdateDTOList集合中
            AttachUpdateDTO attachUpdateDTO = new AttachUpdateDTO();
            attachUpdateDTO.setId(idCardDTO.getId());
            attachUpdateDTO.setIsCover(idCardDTO.getType());
            attachUpdateDTO.setBusinessId(worker.getId().intValue());
            attachUpdateDTO.setBusinessType(businessType);
            attachUpdateDTOList.add(attachUpdateDTO);
        }
        //更新数据库中保存的身份证图片信息
        dubboAttachService.batchUpdateAttachByIdList(attachUpdateDTOList);
        return worker.getId();
    }

    //师傅详情
    @Override
    public WorkerVO getWorkerDetail() {
        //获取用户Id
        Long userId = SecurityContext.getUserId();
        //根据用户id查询数据库中worker的信息
        Worker worker = workerMapper.getWorkerByWorkerId(userId);
        WorkerVO workerVO = new WorkerVO();
        //实例化返回值WorkerVO对象，同名属性赋值
        BeanUtils.copyProperties(worker, workerVO);
        //判断worker是不是null
        if (worker != null) {
            //如果不是null，再相关赋值
            //查询区域
            List<WorkerArea> workerAreas =
                    workerAreaMapper.getAreaByWorkerId(userId);
            if (!workerAreas.isEmpty()) {
                workerVO.setAreaList(PropertiesUtils.copyListProperties(
                        workerAreas, AreaVO.class));
            }
            //查询服务品类
            List<WorkerCategory> workerCategories =
                    workerCategoryMapper.getWorkerCategoryByWorkerId(userId);
            if (!workerCategories.isEmpty()) {
                workerVO.setCategoryList(PropertiesUtils.copyListProperties(
                        workerCategories, CategoryVO.class));
            }
            //查询上传的文件
            List<String> urls = getAttachList(worker.getId());
            workerVO.setAttachList(urls);
            //查询账户余额
            Account account = dubboAccountService.getAccountByUserId(userId);
            AccountVO accountVO = new AccountVO();
            accountVO.setTotalAmount(account != null ? account.getTotalAmount() : 0L);
            workerVO.setAccountVO(accountVO);
            //如果账户审核未通过,需要赋值驳回原因
            Integer auditStatus = worker.getAuditStatus();
            if (AuditStatusEnum.REJECTED.getValue().equals(auditStatus)) {
                //赋值驳回原因
                workerVO.setRejectReason(auditMapper.getRejectReasonByUserId(userId));
            }
        } else {
            //如果是null直接返回一个未注册师傅的状态
            //用户首次登陆workerBO为空对象，设置auditStatus =3 表示未发起审核，未注册师傅。
            workerVO.setAuditStatus(AuditStatusEnum.UNCREATED.getValue());
        }
        return workerVO;
    }

    private List<String> getAttachList(Long id) {
        //http://dev.img.p.yufeiworld.com/attach/93683C87E358401395F8389D193D9A3B.jpeg
        AttachDTO attachDTO = new AttachDTO();
        attachDTO.setBusinessId(id.intValue());
        attachDTO.setBusinessType(businessType);
        List<Attach> attachList = dubboAttachService.getAttachInfo(attachDTO);
        List<String> urls = new ArrayList<>();
        if (!attachList.isEmpty()) {
            attachList.forEach(attach -> {
                urls.add(url + attach.getFileUuid());
            });
        }
        return urls;
    }
}
